/**
*****************************************************************************
* @defgroup SL_IPC Inter Process
* @ingroup SL
* @{
* Copyright (C) 2018 LAN-YOU(GuangZhou). All rights reserved
*
* @par Project:
*      TCU
*
* @par Module:
*      IPC Event
*
* @par Usage Notes:
*      It is a communication middleware for application to set up one to one
*      or one to many communication channel.
*
* @par Author:
*      Nick HUANG
*
*****************************************************************************
*/

#ifndef __IPC_EVENT_H__
#define __IPC_EVENT_H__

#include <vector>
#include <pthread.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/select.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>




namespace ipc_event
{

  // @brief the status of the peer manager definition
  enum PeerStatus_t
  {
    IPC_PEER_UNKNOWN,
	IPC_PEER_CREATED,
	IPC_PEER_INIT,
	IPC_PEER_ACTIVE,
	IPC_PEER_DEACTIVE,
	IPC_PEER_DESTORY
  };

  /**
    *********************************************************************************
	*
	* @brief IPC Peer class
	*
	* @param	Purpose:
	*			store the information of the application.
	*
	* @param	Usage notes:
	*			-
	*
	*********************************************************************************
  */
  class IPCPeer //进程对象的内容信息！创建连接时，创建对象！
  {
  	public:
  	  IPCPeer();
  	  virtual ~IPCPeer();

  	  void setSocket(int fd);   //设置客户进程的fd句柄
  	  int getSocket(void) const;//获取客户进程的fd句柄

  	  void setPeerStatus(PeerStatus_t status);//设置客户进程的状态
  	  PeerStatus_t getPeerStatus(void) const; //获取客户进程的状态

  	private:
  	  // file descriptor of the peer
  	  int socket_m;
  	  // the status of the peer
  	  PeerStatus_t status_m;
  };

  // @brief the set of the peer definition
  typedef std::vector<IPCPeer> IPCPeers_t; //客户进程对象vector容器

  // @brief the set of subscribers definition
  typedef std::vector<int> IPCSubscribers_t;

  /**
    *********************************************************************************
    *
    * @brief IPC Event Channel class
    *
    * @param	Purpose:
    *			store the information of the event channel
    *
    * @param	Usage notes:
    *			-
    *
    *********************************************************************************
  */
  class IPCEventChannel
  {
    public:
      IPCEventChannel();
      virtual ~IPCEventChannel();

      void setEventChannelId(int evtChannelId);
      int getEventChannelId(void) const;

      bool addSubscriber(int subscriber);
      bool delSubscriber(int subscriber);

      IPCSubscribers_t & getSubscribers(void);

    private:
      // channel type
      int eventChannelId_m;
      // the set of the subscriber
      IPCSubscribers_t subscribers_m;
  };

  // @brief the set of event channel definition
  typedef std::vector<IPCEventChannel> IPCEventChannels_t;

  /**
    *********************************************************************************
    *
    * @brief IPC Peer manager class
    *
    * @param	Purpose:
    *			manage the peers and handle the main logic of the peer manager
    *
    * @param	Usage notes:
    *			-
    *
    *********************************************************************************
  */
  class IPCPeerManager
  {
    public:
      static IPCPeerManager  * instance();

      bool initialize(unsigned short port);
      void runEventLoop(void);
      bool finalize(void);

      int getHandle(void) const;
      int getMaxSubscriber(void);
      IPCSubscribers_t getSubscribers(void);

      bool addPeer(void);
      bool handleRequest(int fd);

      void updateFDs(fd_set * fds);

    private:
      IPCPeerManager();

      bool delPeer(int fd);
      bool updateChannel(int fd);
      bool updateChannelByType(int channelId , int fd);
      bool addChannel(int evtType , int fd);

      bool handlePubRequest(int fd ,int type , void * data , int length);
      bool handleSubRequest(int fd , int type);
      bool handleUnsubRequest(int fd , int type);

      bool deliverMsg(int fd , void * data , int length);

      // for singleton usage
      static IPCPeerManager * instance_m;

      // the set of the event channel
      IPCEventChannels_t channels_m;
      // the set of the peer
      IPCPeers_t peers_m;

      // the listening socket
      int listenSock_m;
      // the listening port
      unsigned short port_m;
  };
}

/// @}
#endif

